package outoforder.leetcode01;

import java.util.*;

/**
 * @author shhjiang_001
 * @create 2020-07-11 13:28
 */


// 第255题 设计Twitter
public class Twitter {
    private static int timestamp = 0;
    // 储存推文信息
    private static class Tweet{
        private int id;
        private int time;
        private Tweet next;
        public Tweet(int id,int time){
            this.id = id;
            this.time = time;
            this.next = null;
        }
    }
    // user 类储存用户的信息
    private static class User{
        private int id;
        public Set<Integer> followed;
        public Tweet head;
        public User(int userId){
            followed = new HashSet<>();
            this.id = userId;
            this.head = null;
            follow(id);
        }

        public void follow(int userId) {
            followed.add(userId);
        }
        public void unfollow(int userId){
            if (userId != this.id){
                followed.remove(userId);
            }
        }
        public void post(int tweetId){
            Tweet twt = new Tweet(tweetId, timestamp);
            timestamp++;
            twt.next = head;
            head = twt;
        }
    }
    // 建立一个映射将userId和User对象对应起来
    private HashMap<Integer,User> userMap = new HashMap<>();
    /** Initialize your data structure here. */

    public Twitter() {
    }

    /** Compose a new tweet. */
    public void postTweet(int userId, int tweetId) {
        // 如果userid不存在，则新建
        if (!userMap.containsKey(userId)){
            userMap.put(userId,new User(userId));
        }
        User u = userMap.get(userId);
        u.post(tweetId);

    }

    /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */
    public List<Integer> getNewsFeed(int userId) {
        ArrayList<Integer> res = new ArrayList<>();
        if (!userMap.containsKey(userId)) return res;
        Set<Integer> users = userMap.get(userId).followed;
        // 设计一个队列按照时间排序
        PriorityQueue<Tweet> pq = new PriorityQueue<>(users.size(),(a,b)->(b.time-a.time));
        for (int id:users) {
            Tweet tweet = userMap.get(id).head;
            if (tweet == null) continue;
            pq.add(tweet);
        }
        while (!pq.isEmpty()){
            if (res.size() == 10) break;
            Tweet twt = pq.poll();
            res.add(twt.id);
            if (twt.next != null){
                pq.add(twt.next);
            }
        }
        return res;
    }

    /** Follower follows a followee. If the operation is invalid, it should be a no-op. */
    public void follow(int followerId, int followeeId) {
        if (!userMap.containsKey(followeeId)){
            User u = new User(followeeId);
            userMap.put(followeeId,u);
        }
        userMap.get(followeeId).follow(followeeId);
    }

    /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
    public void unfollow(int followerId, int followeeId) {
        if (userMap.containsKey(followeeId)){
            User user = userMap.get(followeeId);
            user.unfollow(followeeId);
        }
    }
}
